#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "list.h"
#include "msg_queue_peer.h"
#include "cJSON.h"
#include <pthread.h>
#include "shmem.h"

#define PORT 8888
#define BUFFER_SIZE 1024

// 消息队列结构体
struct que_order
{
    long tag;     // 消息队列的设备类型
    int key;      // 数据节点唯一标识
    char val[32]; // 数据
};
// 反序列化处理缓存区
typedef struct
{
    char name[32];
    char key[32];
    char val[32];
} DataItem;
// 共享内存结构体
union val_t
{
    int b_val;   // bool 类型存储空间
    int i_val;   // 整形值存储空间
    float f_val; // 浮点值存储空间
};

struct mb_node
{
    int key;             // 唯一键值
    int type;            // 数据点类型
    int dev_type;        // 数据点属于哪个设备，根据网关支持的设备自行定义
    union val_t old_val; // 变化上报后需要更新旧值
    union val_t new_val; // 从共享内存取出最新数据，放到 new_val 中
    int ret;             // 默认为-1，采集成功后设置为 0，采集失败再置-1
};

// 全局变量区
char shared_memory[BUFFER_SIZE];
char command_dev[BUFFER_SIZE];
char senddata[BUFFER_SIZE];
struct que_order *msg;
struct shm_param *para;
DataItem *dataArray;
int *Count;

// 控制命令下发序列化函数
char *serializeJSON(const char *dev, const char *val)
{
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "dev", dev);
    cJSON_AddStringToObject(root, "val", val);
    char *jsonStr = cJSON_Print(root);
    cJSON_Delete(root);
    return jsonStr;
}

// 接受上报反序列化函数
void deserializeJSON(const char *buf, DataItem *dataArray, int *Count)
{
    cJSON *root = cJSON_Parse(buf);
    cJSON *dataArrayJSON = cJSON_GetObjectItem(root, "data");
    *Count = cJSON_GetArraySize(dataArrayJSON);
    for (int i = 0; i < *Count; i++)
    {
        cJSON *itemJSON = cJSON_GetArrayItem(dataArrayJSON, i);
        cJSON *nameJSON = cJSON_GetObjectItem(itemJSON, "name");
        cJSON *keyJSON = cJSON_GetObjectItem(itemJSON, "key");
        cJSON *valJSON = cJSON_GetObjectItem(itemJSON, "val");
        strcpy(dataArray[i].name, nameJSON->valuestring);
        strcpy(dataArray[i].key, keyJSON->valuestring);
        strcpy(dataArray[i].val, valJSON->valuestring);
    }
    cJSON_Delete(root);
}

// 上报处理函数
void *handleClientThread(void *arg)
{
    int clientSocket = *(int *)arg;
    char buffer[BUFFER_SIZE];
    while (1)
    {
        ssize_t bytesRead = recv(clientSocket, buffer, BUFFER_SIZE - 1, 0);
        if (bytesRead <= 0)
        {
            perror("接收错误或客户端断开连接");
            break;
        }
        buffer[bytesRead] = '\0';
        strcpy(shared_memory, buffer);
        printf("接收成功：收到数据 %s\n", buffer);
    }

    // 数据处理
    deserializeJSON(buffer, dataArray, Count);
    struct mb_node *node;
    for (int j = 0; j < 6; j++)
    {
        node[j].key = (int)dataArray[j].key;
        if (j < 2)
        {
            node[j].type = 3;
            float f = atof(dataArray->val);
            node[j].new_val.f_val = f;
        }
        else
        {
            node[j].type = 1;
            node[j].new_val.i_val = (int)dataArray->val;
        }
        node[j].dev_type = 3;
        node[j].ret = 0;
    }

    // 读取共享内存
    int rec = shm_init(para, "five", 1024);
    if (rec == -1)
    {
        perror("共享内存初始化失败");
    }
    int *num = shm_getaddr(para);
    if (NULL == num)
    {
        perror("获取共享内存失败");
    }
    node = num + 1;
    shm_write(para, node, sizeof(node));
    close(clientSocket);
    return NULL;
}

// 命令下达函数
void *sendDataToClientThread(void *arg)
{
    int clientSocket = *(int *)arg;
    while (1)
    {
        // 读取消息队列数据
        if (msg_queue_recv("five", &msg, sizeof(msg), 3, 0) == -1)
        {
            perror("读取消息队列错误");
            break;
        }

        // 判断控制哪个设备
        switch (msg->key)
        {
        case 303:
            strcpy(command_dev, "fan");
            break;
        case 304:
            strcpy(command_dev, "motor");
            break;
        case 305:
            strcpy(command_dev, "led_pwm");
            break;
        default:
            printf("未知的 key 值：%d\n", msg->key);
            break;
        }
        // 将数据序列化后放入发送缓存区
        char *message = serializeJSON(command_dev, msg->val);
        ssize_t bytesSent = send(clientSocket, message, strlen(message), 0);
        if (bytesSent <= 0)
        {
            perror("发送错误");
            break;
        }
        printf("发送成功：已发送消息 %s\n", message);
        // 释放序列化后动态分配的内存
        free(message);
    }
    return NULL;
}

int main()
{
    int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1)
    {
        perror("创建套接字失败");
        return -1;
    }

    struct sockaddr_in serverAddress;
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(PORT);

    if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) == -1)
    {
        perror("绑定失败");
        close(serverSocket);
        return -1;
    }

    if (listen(serverSocket, 5) == -1)
    {
        perror("监听失败");
        close(serverSocket);
        return -1;
    }

    printf("服务器正在监听端口 %d...\n", PORT);

    int clientSocket = accept(serverSocket, NULL, NULL);
    if (clientSocket == -1)
    {
        perror("接受连接失败");
        close(serverSocket);
        return -1;
    }

    printf("连接成功！客户端已连接。\n");

    pthread_t handleClientThreadID, sendDataToClientThreadID;
    pthread_create(&handleClientThreadID, NULL, handleClientThread, &clientSocket);
    pthread_create(&sendDataToClientThreadID, NULL, sendDataToClientThread, &clientSocket);

    pthread_join(handleClientThreadID, NULL);
    pthread_join(sendDataToClientThreadID, NULL);

    close(clientSocket);
    close(serverSocket);

    return 0;
}